#ifndef __DS_H__
#define __DS_H__

#define  DS_OK          0
#define  DS_ERROR      -1


#define DS_ALIGNMENT   sizeof(unsigned long)

#define align(d, a)     (((d) + (a - 1)) & ~(a - 1))
#define align_ptr(p, a)                                                   \
    (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))

#define DS_MAX_ALLOC_FROM_POOL  (4096 - 1)

#define DS_HASH(key, c) ((int) key * 31 + c)

/* ************ Help Method ************** */
off_t DS_Atoof(u_char *line, size_t n);


/* ************String************* */
typedef struct String {
    u_char *data;
    size_t len;
}String;


/* **********Memory Pool********** */
typedef struct ds_pool_large_s {
    struct ds_pool_large_s     *next;
    void                 *alloc;
}ds_pool_large_s;

typedef struct ds_pool_data_s{
    u_char               *last;
    u_char               *end;
    struct ds_pool_s    *next;
    unsigned int    failed;
} ds_pool_data_s;

typedef struct ds_pool_s {
    ds_pool_data_s  d;
    size_t  max;
    struct Chain *chain;
    struct ds_pool_s    *current;
    ds_pool_large_s     *large;
}ds_pool_s;

void *DS_Alloc(size_t size);
ds_pool_s *DS_CreatePool(size_t size);
void DS_DestroyPool(ds_pool_s *pool);
void *DS_Palloc(ds_pool_s *pool, size_t size);
void *DS_Pcalloc(ds_pool_s *pool, size_t size);

/* **********End********** */



/* **********Unit Storage: Buf and Chain********** */
typedef struct Buf {
    u_char  *pos;
    u_char  *last;

    off_t file_pos;
    off_t file_last;

    u_char  *start;         
    u_char  *end;

    int fileDes;
    unsigned    in_file:1;
}Buf;

#define DS_BUF_SIZE(b)                                                      \
    (b->in_file ? (off_t) (b->file_last - b->file_pos):                      \
                            (b->last - b->pos))

typedef struct Chain {
    Buf    *buf;
    struct Chain  *next;
}Chain;


Buf * DS_CreateTempBuf(ds_pool_s *pool, size_t size);
Chain * DS_AllocChainLink(ds_pool_s *pool);

#define DS_FreeChain(pool, cl)                                             \
    cl->next = pool->chain;                                                  \
    pool->chain = cl
    
/* **********End********** */



/* **********Array********** */
typedef struct ds_array_s {
    void        *elts;
    unsigned int   nelts;
    size_t       size;
    unsigned int   nalloc;
    ds_pool_s  *pool;
}ds_array_s;

ds_array_s *DS_ArrayCreate(ds_pool_s *p, unsigned int n, size_t size);
void DS_ArrayDestroy(ds_array_s *a);
void *DS_ArrayPush(ds_array_s *a);

/* **********End********** */


#endif

